﻿// ===============================================================================
// XCI.NET 西安交通信息WinForm开发框架 2018 版权所有
// ===============================================================================
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Drawing;
using DevExpress.XtraEditors.Popup;
using DevExpress.XtraEditors.Registrator;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraEditors.ViewInfo;
using XCI.Extensions;
using XCI.Helper;

namespace XCI.Windows
{
    /// <summary>
    /// 支持数据绑定的带图标下拉控件
    /// </summary>
    [System.ComponentModel.DesignerCategory("Code")]
    [ToolboxItem(true)]
    public class ImageComboBoxEditx : DevExpress.XtraEditors.ImageComboBoxEdit
    {
        static ImageComboBoxEditx()
        {
            RepositoryItemImageComboBoxEditx.RegisterImageComboBoxEditx();
        }

        public ImageComboBoxEditx()
        {
        }

        private object dataSource;
        private CurrencyManager dataManager;
        private object _lazyEditValue;

        /// <summary>
        /// 指示要为此控件中的项显示的属性
        /// </summary>
        [Category("XCI数据"), Description("指示要为此控件中的项显示的属性")]
        public string DisplayMember { get; set; }

        /// <summary>
        /// 指示用作控件中项的实际值的属性
        /// </summary>
        [Category("XCI数据"), Description("指示用作控件中项的实际值的属性")]
        public string ValueMember { get; set; }

        /// <summary>
        /// 指示用作控件中项的图标索引的属性
        /// </summary>
        [Category("XCI数据"), Description("指示用作控件中项的图标索引的属性")]
        public string ImageIndexMember { get; set; }

        /// <summary>
        /// 数据源
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public object DataSource
        {
            get { return dataSource; }
            set
            {
                if (value != null && !(value is IList || value is IListSource))
                    throw new ArgumentException("无效数据源");
                if (dataSource == value) return;

                dataSource = value;
                if (((dataSource != null) && (BindingContext != null)) && (dataSource != Convert.DBNull))
                {
                    dataManager = (CurrencyManager)this.BindingContext[dataSource];
                }

                this.Properties.Items.BeginUpdate();
                foreach (object item in dataManager.List)
                {
                    object v = CurrencyManagerHelper.GetValue(dataManager, item, ValueMember);
                    object d = CurrencyManagerHelper.GetValue(dataManager, item, DisplayMember);
                    int imageIndex = -1;
                    if (!string.IsNullOrEmpty(ImageIndexMember))
                    {
                        imageIndex = CurrencyManagerHelper.GetValue(dataManager, item, ImageIndexMember).ToInt();
                    }
                    string description = string.Empty;
                    if (d != null)
                    {
                        description = d.ToString();
                    }
                    this.Properties.Items.Add(new ImageComboBoxItem(description, v, imageIndex));
                }
                this.Properties.Items.EndUpdate();
                if (_lazyEditValue != null)
                {
                    SelectedValue = _lazyEditValue;
                }
            }
        }

        /// <summary>
        /// 文本值
        /// </summary>
        [Bindable(false), Browsable(false)]
        public override string Text
        {
            get { return base.Text; }
            set { base.Text = value; }
        }

        /// <summary>
        /// 获取或设置指定当前选定值。
        /// </summary>
        [Category("Data"), Description("获取或设置指定当前选定值。")]
        [Bindable(true)][DefaultValue(null)]
        public new object EditValue
        {
            get { return SelectedValue; }
            set
            {
                _lazyEditValue = value;
                SelectedValue = value;
            }
        }

        /// <summary>
        /// 获取或设置选中值
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public object SelectedValue
        {
            get
            {
                if (DataSource == null)
                {
                    return base.EditValue;
                }
                object currentItem = CurrencyManagerHelper.GetItem(dataManager, SelectedIndex);
                return CurrencyManagerHelper.GetValue(dataManager, currentItem, ValueMember);
            }
            set
            {
                if (DataSource == null)
                {
                    base.EditValue = value;
                    return;
                }
                if (value == null) this.SelectedIndex = -1;

                if (dataManager == null) return;
                string propertyName = ValueMember;
                if (string.IsNullOrEmpty(propertyName))
                    throw new InvalidOperationException("请设置ValueMember");
                this.SelectedIndex = CurrencyManagerHelper.GetIndex(dataManager, propertyName, value);
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public new RepositoryItemImageComboBoxEditx Properties => base.Properties as RepositoryItemImageComboBoxEditx;

        public override string EditorTypeName => RepositoryItemImageComboBoxEditx.CustomEditName;
    }

    [UserRepositoryItem("RegisterImageComboBoxEditx")]
    public class RepositoryItemImageComboBoxEditx : RepositoryItemImageComboBox
    {
        static RepositoryItemImageComboBoxEditx()
        {
            RegisterImageComboBoxEditx();
        }

        public const string CustomEditName = "ImageComboBoxEditx";

        public RepositoryItemImageComboBoxEditx()
        {
        }

        public override string EditorTypeName => CustomEditName;

        public static void RegisterImageComboBoxEditx()
        {
            Image img = null;
            EditorRegistrationInfo.Default.Editors.Add(new EditorClassInfo(CustomEditName, typeof(ImageComboBoxEditx), typeof(RepositoryItemImageComboBoxEditx), typeof(ImageComboBoxEditxViewInfo), new ImageComboBoxEditxPainter(), true, img));
        }

        public override void Assign(RepositoryItem item)
        {
            BeginUpdate();
            try
            {
                base.Assign(item);
                if (!(item is RepositoryItemImageComboBoxEditx source)) return;
                //
            }
            finally
            {
                EndUpdate();
            }
        }
    }

    public class ImageComboBoxEditxViewInfo : ImageComboBoxEditViewInfo
    {
        public ImageComboBoxEditxViewInfo(RepositoryItem item) : base(item)
        {
        }
    }

    public class ImageComboBoxEditxPainter : ImageComboBoxEditPainter
    {
        public ImageComboBoxEditxPainter()
        {
        }
    }

    public class ImageComboBoxEditxPopupForm : PopupImageComboBoxEditListBoxForm
    {
        public ImageComboBoxEditxPopupForm(ImageComboBoxEditx ownerEdit) : base(ownerEdit)
        {
        }
    }
}